#include "dynamicArray.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int dynamicArrayInit(DynamicArray *array, int capacity) // 动态数组初始化
{
    if (array == NULL)
    {
        return 0;
    }
    if (capacity <= 0)
    {
        capacity = 10;
    }
    array->m_size = 0;
    array->m_capacity = capacity;
    array->data = (ELEMENT_TYPE *)malloc(sizeof(ELEMENT_TYPE) * array->m_capacity);

    if (array->data == NULL)
    {
        printf("malloc error");
        return -1;
    }
    memset(array->data, 0, sizeof(ELEMENT_TYPE) * array->m_capacity); // 清除脏数据
    return 0;
}
// 静态数组：扩大容量
static int expendCapaCity(DynamicArray *array)
{
#if 0
    if (array == NULL)
    {
        return -1;
    }

    int newCapacity = array->m_capacity<<1;
    ELEMENT_TYPE * newData = (ELEMENT_TYPE *)realloc(array->data, sizeof(ELEMENT_TYPE) * newCapacity);

    if (newData == NULL)
    {
        printf("realloc error\n");
        return -1;
    }

    array->data = newData;
    array->m_capacity = newCapacity;
#endif

    ELEMENT_TYPE *tmp = array->data;

    int newCapacity = array->m_capacity + (array->m_capacity >> 1);
    array->data = (ELEMENT_TYPE *)malloc(sizeof(ELEMENT_TYPE) * newCapacity);
    if (array->data == NULL)
    {
        printf("malloc error");
        return -1;
    }

    for (int idx = 0; idx < array->m_size; idx++)
    {
        array->data[idx] = tmp[idx];
    }

    free(tmp);
    array->m_capacity = newCapacity;
    return 0;
}

// 动态数组插入元素（默认插到数组末尾）
int dynamicArrayInsert(DynamicArray *array, ELEMENT_TYPE data)
{
    if (array == NULL)
    {
        return -1;
    }
    if (array->m_size == array->m_capacity)
    {
        expendCapaCity(array);
    }
    // 讲data元素放到数组的位置上
    array->data[array->m_size] = data;
    // 元素个数加一
    array->m_size++;
    return 0;
}
// 插入指定位置
int dynamicArrayAppointPosInsert(DynamicArray *array, int pos, ELEMENT_TYPE data)
{
    if (array == NULL)
    {
        return -1;
    }
    if (pos < 0 || pos > array->m_size)
    {
        printf("pos error:\n");
        return -1;
    }
    if (array->m_size == array->m_capacity)
    {
        expendCapaCity(array);
    }
    for (int idx = array->m_size; idx > pos; idx--)
    {
        array->data[idx] = array->data[idx - 1];
    }
    array->data[pos] = data;
    array->m_size++;
    return 0;
}

int travelArrayElement(DynamicArray *array, void (*printFunc)(ELEMENT_TYPE arg)) /*遍历动态数组的元素 */
{
    for (int idx = 0; idx < array->m_size; idx++)
    {
        printFunc(array->data[idx]);
    }
    printf("\n");
    return 0;
}

// 缩容
int shrinkCapacity(DynamicArray *array)
{
    ELEMENT_TYPE *tmp = array->data;

    int newCapacity = array->m_capacity + (array->m_capacity << 1);
    array->data = (ELEMENT_TYPE *)malloc(sizeof(ELEMENT_TYPE) * newCapacity);
    if (array->data == NULL)
    {
        printf("malloc error");
        return -1;
    }

    for (int idx = 0; idx < array->m_size; idx++)
    {
        array->data[idx] = tmp[idx];
    }

    free(tmp);
    array->m_capacity = newCapacity;
    return 0;
}

int dynamicArrayDelete(DynamicArray *array) // 从末尾删除
{
    dynamicArrayAppointPosDelete(array, array->m_size - 1);
}

int dynamicArrayAppointPosDelete(DynamicArray *array, int pos)
{
    if (array == NULL)
    {
        return -1;
    }

    if (pos < 0 || pos >= array->m_size)
    {
        printf("pos error:");
        return -1;
    }

    // 从指定位置向后移动元素
    for (int i = pos; i < array->m_size - 1; i++)
    {
        array->data[i] = array->data[i + 1];
    }

    array->m_size--; // 更新数组的属性

    array->data[array->m_size] = 0;

    return 0;
}

static int appointValGetPos(DynamicArray *array, ELEMENT_TYPE data) /*动态数组删除指定位置元素 */
{
    for (size_t i = 0; i < array->m_size; i++)
    {
        if (array->data[i] == data)
        {
            dynamicArrayAppointPosDelete(array, array->data[i]);
        }
    }
    return -1;
}

int dynamicArrayAppointDataDelete(DynamicArray *array, ELEMENT_TYPE data) // 按指定元素释放
{
    if (array == NULL)
    {
        return -1;
    }

    for (size_t i = 0; i < array->m_size; i++)
    {
        if (array->data[i] == data)
        {
            dynamicArrayAppointPosDelete(array, array->data[i]);
        }
    }

    return 0;
}

int dynamicArrayDestroy(DynamicArray *array) // 内存释放
{

    if (array->data != NULL)
    {
        free(array->data);
        array->data = NULL;
    }

    return 0;
}
